#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_scale.h"
using namespace mdtx::online;

#include "indi_common.h"

using rollmad_ = indi2<indicator::rollmad>;

//' Rolling MAD
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param constant scaling factor applied to MAD
//' @return List of median and MAD
//' @export
// [[Rcpp::export(rng = false)]]
List rollmad(NumericVector x, int period, double constant = 1.4826)
{
    auto c = rollmad_::create_t(period, constant);
    auto ans = rollmad_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollmad_new(int period, double constant = 1.4826)
{
    return rollmad_::create(period, constant);
}

// [[Rcpp::export(rng = false)]]
List rollmad_run(SEXP ptr, NumericVector x)
{
    auto ans = rollmad_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

using rolliqr_ = indi2<indicator::rolliqr>;

//' Rolling IQR
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param q1 quantile of first Q
//' @param q3 quantile of third Q
//' @return List of median and IQR
//' @export
// [[Rcpp::export(rng = false)]]
List rolliqr(NumericVector x, int period, double q1 = 0.25, double q3 = 0.75)
{
    auto c = rolliqr_::create_t(period, q1, q3);
    auto ans = rolliqr_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rolliqr_new(int period, double q1 = 0.25, double q3 = 0.75)
{
    return rolliqr_::create(period, q1, q3);
}

// [[Rcpp::export(rng = false)]]
List rolliqr_run(SEXP ptr, NumericVector x)
{
    auto ans = rolliqr_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

using rolliqr_cu_ = indi2<indicator::rolliqr_cu>;

//' Cumulative IQR
//'
//' @param x Numeric vector
//' @param q1 quantile of first Q
//' @param q3 quantile of third Q
//' @param k parameter passed to KLL sketch
//' @return List of median and IQR
//' @export
// [[Rcpp::export]]
List rolliqr_cu(NumericVector x, double q1 = 0.25, double q3 = 0.75, int k = 200)
{
    auto c = rolliqr_cu_::create_t(q1, q3, k);
    auto ans = rolliqr_cu_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

// [[Rcpp::export]]
SEXP rolliqr_cu_new(double q1 = 0.25, double q3 = 0.75, int k = 200)
{
    return rolliqr_cu_::create(q1, q3, k);
}

// [[Rcpp::export]]
List rolliqr_cu_run(SEXP ptr, NumericVector x)
{
    auto ans = rolliqr_cu_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

using rollSn_ = indi2<indicator::rollSn>;

//' Rolling Sn scale estimator
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param constant scaling factor applied to Sn
//' @return List of median and Sn
//' @export
// [[Rcpp::export(rng = false)]]
List rollSn(NumericVector x, int period, double constant = 1.1926)
{
    auto c = rollSn_::create_t(period, constant);
    auto ans = rollSn_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollSn_new(int period, double constant = 1.1926)
{
    return rollSn_::create(period, constant);
}

// [[Rcpp::export(rng = false)]]
List rollSn_run(SEXP ptr, NumericVector x)
{
    auto ans = rollSn_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

using rollQn_ = indi2<indicator::rollQn>;

//' Rolling Qn scale estimator
//'
//' @param x Numeric vector
//' @param period Period of rolling window
//' @param constant scaling factor applied to Qn
//' @return List of median and Qn
//' @export
// [[Rcpp::export(rng = false)]]
List rollQn(NumericVector x, int period, double constant = 2.21914)
{
    auto c = rollQn_::create_t(period, constant);
    auto ans = rollQn_::run_t(c, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP rollQn_new(int period, double constant = 2.21914)
{
    return rollQn_::create(period, constant);
}

// [[Rcpp::export(rng = false)]]
List rollQn_run(SEXP ptr, NumericVector x)
{
    auto ans = rollQn_::run(ptr, x);
    ans.names() = CharacterVector::create("center", "scale");
    return ans;
}
